/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.pa165.languageschoolservice.serviceImpl;

import com.pa165.languageschoolpersistence.DAO.CourseDAO;
import com.pa165.languageschoolpersistence.Exceptions.IllegalArgumentPersistenceException;
import com.pa165.languageschoolpersistence.Exceptions.ServiceFailureException;
import com.pa165.languageschoolpersistence.entities.Course;
import com.pa165.languageschoolpersistence.entities.LanguageSpoken;
import com.pa165.languageschoolservice.DTO.CourseDTO;
import com.pa165.languageschoolservice.service.CourseService;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @Aleksei Penzentcev
 */
@Service("courseService")
public class CourseServiceImpl implements CourseService {

    @Resource(name = "courseDAO")
    private CourseDAO courseDAO;
    @Autowired
    private Mapper mapper;

    public Mapper getMapper() {
        return mapper;
    }

    public void setMapper(Mapper mapper) {
        this.mapper = mapper;
    }

    public CourseDAO getCourseDAO() {
        return courseDAO;
    }

    public void setCourseDAO(CourseDAO courseDAO) {
        this.courseDAO = courseDAO;
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    @Transactional(readOnly = true)
    public CourseDTO get(Long id) throws  IllegalArgumentPersistenceException{
        if (id == null) {
            throw new IllegalArgumentException("Id is null CourseServiceImpl.get");
        }
        Course course = courseDAO.get(id);
        CourseDTO courseDTO = null;
        if (course != null) {
            courseDTO = mapper.map(course, CourseDTO.class);
        }
        return courseDTO;
    }

   
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public CourseDTO add(@Valid CourseDTO courseDTO) throws ServiceFailureException {
        if (courseDTO == null) {
            throw new IllegalArgumentException("courseDTO is null in  CourseServiceImpl.add ");
        }
        List<Course> courses = courseDAO.findByName(courseDTO.getName());
        if (courses.size() > 0) {
            throw new IllegalArgumentException("Trying to add course with name " + courseDTO.getName() + ", which already exists");
        }
        Course course = mapper.map(courseDTO, Course.class);
        courseDAO.add(course);
        return mapper.map(course, CourseDTO.class);
    }

   
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void remove(@Valid CourseDTO courseDTO) throws  IllegalArgumentPersistenceException{
        if (courseDTO == null) {
            throw new IllegalArgumentException("courseDTO is null in  CourseServiceImpl.remove ");
        }
        if (courseDTO.getId() == null) {
            throw new IllegalArgumentException("courseDTO.Id is null in CourseServiceImpl.remove ");
        }
        Course course = mapper.map(courseDTO, Course.class);
        courseDAO.remove(course);
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public CourseDTO modify(@Valid CourseDTO courseDTO) throws  IllegalArgumentPersistenceException {
        if (courseDTO == null) {
            throw new IllegalArgumentException("courseDTO is null in  CourseServiceImpl.modify ");
        }
        if (courseDTO.getId() == null) {
            throw new IllegalArgumentException("courseDTO.Id is null in CourseServiceImpl.modify ");
        }
        String name = courseDTO.getName();
        List<Course> courses = courseDAO.findByName(name);
        if (((courses.size() > 0) && (!courses.get(0).getId().equals(courseDTO.getId())))) {
            throw new IllegalArgumentException("Trying to modify course with name " + name + ", which already exists");
        }
        Course course = mapper.map(courseDTO, Course.class);
        courseDAO.modify(course);
        return mapper.map(course, CourseDTO.class);
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    @Transactional(readOnly = true)
    public List<CourseDTO> getAll() {
        List<Course> courses = courseDAO.getAll();
        List<CourseDTO> result = new ArrayList<CourseDTO>();
        for (Course course : courses) {
            result.add(mapper.map(course, CourseDTO.class));
        }
        return result;
    }

     @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    @Transactional(readOnly = true)
    public List<CourseDTO> findByName(String name) throws  IllegalArgumentPersistenceException{
        if (name == null) {
            throw new IllegalArgumentException("name is null in CourseServiceImpl.findByName ");
        }
        List<Course> courses = courseDAO.findByName(name);
        List<CourseDTO> result = new ArrayList<CourseDTO>();
        for (Course course : courses) {
            result.add(mapper.map(course, CourseDTO.class));
        }
        return result;
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    @Transactional(readOnly = true)
    public List<CourseDTO> findByLanguage(LanguageSpoken language) throws  IllegalArgumentPersistenceException{
        if (language == null) {
            throw new IllegalArgumentException("language is null in CourseServiceImpl.findByLanguage ");
        }
        List<Course> courses = courseDAO.findByLanguage(language);
        List<CourseDTO> result = new ArrayList<CourseDTO>();
        for (Course course : courses) {
            result.add(mapper.map(course, CourseDTO.class));
        }
        return result;
    }
}
